<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>ColumNav Documentation</title>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/container/container_core-min.js"></script>
    <script type="text/javascript" src="./js/carousel.js"></script>
    <script type="text/javascript" src="./js/columnav.js"></script>
    <link href="./css/carousel.css" rel="stylesheet" type="text/css"/>
    <link href="./css/columnav.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript">
      try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}
      function init() {
          var cn_cfg = { prevElement: 'columnav-prev', datasource: 'contents.xml' };
          var cn = new YAHOO.extension.ColumNav('columnav', cn_cfg);
      }
      YAHOO.util.Event.addListener(window, 'load', init);
    </script>
    <link href="./css/stringify.css" rel="stylesheet" type="text/css"/>
    <style type="text/css">
      .carousel-component ul.carousel-list li div { height: 200px; }
    </style>
  </head>
  <body>
    <div id="main">
      <div id="content">

        <h1>ColumNav</h1>

        <div class="prevButton">
          <a href="javascript:void(0)" id="columnav-prev">&lt; back</a>
        </div>
        <div id="columnav" class="carousel-component">
          <div class="carousel-clip-region">
            <ul class="carousel-list"></ul>
          </div>
        </div>

<!-- Markdown generated HTML begins here -->
<h2>Overview</h2>

<p>ColumNav is a hierarchical menu implementation utilizing Bill Scott's <a href="http://developer.yahoo.com/yui/">Yahoo UI</a> <a href="http://billwscott.com/carousel/">Carousel component</a>. Content is loaded from an unordered list and displayed in a scrollable viewport, similar to Column View in the <a href="http://en.wikipedia.org/wiki/Image:Finder1.png">Mac OS X Finder</a>. Features include:</p>

<ul>
<li>infinite extensibility using Ajax to build sub-menus</li>
<li>instantiation from DOM or JSON data sources</li>
<li>a highly customizable look and feel using CSS</li>
<li>support for multiple columns</li>
<li>support for keyboard-only navigation (<kbd>CTRL</kbd> + arrow keys)</li>
<li>cross-browser compatibility</li>
</ul>

<h2>Examples</h2>

<p>The following examples demonstrate the various ways content can be loaded when initializing a ColumNav object:</p>

<ul>
<li><a href="examples/dom-getElementById.html">from a DOM object using <code>document.getElementById</code></a></li>
<li><a href="examples/dom-createElement.html">from a DOM object using <code>document.createElement</code></a></li>
<li><a href="examples/dom-ajax.html">from a DOM object via Ajax</a></li>
<li><a href="examples/json-literal.html">from a JSON object literal</a></li>
<li><a href="examples/json-ajax.html">from a JSON object via Ajax</a></li>
</ul>

<p>Additional examples, demonstrating some customizations:</p>

<ul>
<li><a href="examples/infinite.html">Infinite depth</a>: unlimited sub-menus using Ajax</li>
<li><a href="examples/custom-icons.html">Custom icons</a>: using CSS to fine tune images</li>
<li><a href="examples/link-action.html">Link actions</a>: preprocessing clicks on leaf node links</li>
<li><a href="examples/multi-col.html">Multiple columns</a></li>
<li><a href="examples/preview-pane.html">Preview pane</a>: mimics the preview icon feature of the Mac OS X Finder</li>
</ul>

<h2>Download</h2>

<ul>
<li><strong><a href="http://stringify.com/misc/columnav-0.9.6.zip">columnav-0.9.6.zip</a></strong> (3 Jun 2007): includes source code, examples, and this documentation</li>
<li>the latest version can always be found <a href="http://stringify.com/columnav/">here</a></li>
</ul>

<h2>Usage</h2>

<p>Setting up ColumNav is a straightforward process of providing the proper HTML, JavaScript, and CSS configuration, along with creating the data source. Understanding how a data source is formed and processed is key to using ColumNav, so it is presented first below.</p>

<h3>Data sources</h3>

<p>You have two types of objects to choose from when building a data source: DOM or JSON. In either case, the object represents a normal HTML unordered list. Each list item contains a link and possibly a nested sub-list. For example, a DOM representation of basketball teams might look like this:</p>

<pre><code>&lt;ul id="basketball-list"&gt;
  &lt;li&gt;
    &lt;a href="http://sports.yahoo.com/nba/"&gt;NBA&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;
        &lt;a href=""&gt;Atlantic&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/bos"&gt;Boston Celtics&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/njn"&gt;New Jersey Nets&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/nyk"&gt;New York Knicks&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/phi"&gt;Philadelphia 76ers&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/tor"&gt;Toronto Raptors&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href="examples/ajax/ncaa/index.xml" rel="ajax"&gt;NCAA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>

<p>The equivalent JSON object would look like this:</p>

<pre><code>{ "ul": {
    "@id": "basketball-list",
    "li": [
      { "a": { "@href": "http://sports.yahoo.com/nba/", "#text": "NBA" },
        "ul": {
          "li": [
            { "a": { "@href": "", "#text": "Atlantic" },
              "ul": {
                "li": [
                  { "a": { "@href": "http://sports.yahoo.com/nba/teams/bos", "#text": "Boston Celtics" } },
                  { "a": { "@href": "http://sports.yahoo.com/nba/teams/njn", "#text": "New Jersey Nets" } },
                  { "a": { "@href": "http://sports.yahoo.com/nba/teams/nyk", "#text": "New York Knicks" } },
                  { "a": { "@href": "http://sports.yahoo.com/nba/teams/phi", "#text": "Philadelphia 76ers" } },
                  { "a": { "@href": "http://sports.yahoo.com/nba/teams/tor", "#text": "Toronto Raptors" } }
                ]
            } },
          ]
      } },
      { "a": { "@href": "ajax/json/ncaa/index.json", "@rel": "ajax", "#text": "NCAA" } }
    ]
} }
</code></pre>

<p>When imported into the ColumNav component, the data source is divided into "panes" based on each item's position in the list. Top-level items are viewable at first ("NBA" and "NCAA" above), while nested items occupy subsequent panes. Bottom-level items act as normal links unless their <code>rel</code> attribute contains the flag <code>ajax</code>. In this case, the URL specified in the <code>href</code> attribute is used to retrieve the next list in the series via Ajax.</p>

<p>ColumNav instances can be initialized using a pre-built object (DOM or JSON) or from an object acquired via Ajax. See the <code>datasource</code> configuration property below.</p>

<p><strong>IMPORTANT: Data sources loaded though Ajax must be served with a proper mime type.</strong> XML sources must have a mime type of <code>application/xml</code> or <code>application/xhtml+xml</code>, while JSON sources must be sent as <code>application/json</code>.</p>

<p>All link attributes in the data source are propagated to the ColumNav. You can, for example, specify a <code>class</code> attribute for a particular link, and use that value for fine-grained CSS control. See the CSS section below.</p>

<h3>HTML</h3>

<p>The HTML structure of each ColumNav should conform to that expected by the Carousel component script:</p>

<pre><code>&lt;div id="mycolumnav" class="carousel-component"&gt;
  &lt;div class="carousel-clip-region"&gt;
    &lt;ul class="carousel-list"&gt;&lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;
</code></pre>

<p>The specific class names are required by the Carousel. See the <a href="http://billwscott.com/carousel/">Carousel documentation</a> for more information. The <code>id</code> value is arbitrary, and will be passed as the first argument to the ColumNav constructor (see below).</p>

<p>Additionally, you can provide a "back" button for retracing your steps:</p>

<pre><code>&lt;div class="prevButton"&gt;
  &lt;a href="javascript:void(0)" id="mycolumnav-prev"&gt;&amp;lt; back&lt;/a&gt;
&lt;/div&gt;
</code></pre>

<p>The HTML can be anything, provided the clickable element has an <code>id</code> attribute. The <code>id</code> will be passed to the ColumNav constructor to enable the button. A ColumNav instance can have multiple back buttons. See the configuration properties below.</p>

<h3>JavaScript</h3>

<p>ColumNav relies on Carousel, which in turn relies on the <a href="http://developer.yahoo.com/yui/">Yahoo UI Library</a> (version 0.12 or above). Include the required files in the <code>&lt;head&gt;</code> of your document. Note that you can include <a href="http://developer.yahoo.com/yui/articles/hosting/">YUI files hosted on Yahoo servers</a>. If you are going to be processing JSON objects, include the <a href="http://www.json.org/json.js">JSON parsing script</a> as well.</p>

<pre><code>&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/container/container_core-min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="carousel.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="columnav.js"&gt;&lt;/script&gt;
&lt;!-- if JSON data sources: --&gt;
&lt;script type="text/javascript" src="json.js"&gt;&lt;/script&gt;
</code></pre>

<p>Since a ColumNav instance depends on the existence of a specific HTML element, it is best to instantiate it after page load. For instance:</p>

<pre><code>&lt;script type="text/javascript"&gt;
  function init() {
      // ... do other stuff first, perhaps ...
      var cn_cfg = { prevElement: 'mycolumnav-prev'', datasource: some_url_or_object };
      var cn = new YAHOO.extension.ColumNav('mycolumnav', cn_cfg);
  }
  YAHOO.util.Event.addListener(window, 'load', init);
&lt;/script&gt;
</code></pre>

<p>The ColumNav constructor accepts two arguments: the <code>id</code> of the outermost <code>&lt;div&gt;</code> (the one with <code>class="carousel-component"</code>), and an object containing configuration properties. These properties are name/value pairs governing the ColumNav look and behavior:</p>

<ul>
<li><p><strong>datasource:</strong> (required) a string representing the URL to call via Ajax in order to load the initial items, <strong>OR</strong> a reference to an object (DOM or JSON) containing the necessary list structure.</p></li>
<li><p><strong>prevElement:</strong> (optional) The <code>id</code> or DOM object reference of the HTML element that will provide the previous navigation control. Can be an array of <code>id</code>s or DOM objects.</p></li>
<li><p><strong>linkAction:</strong> (optional) a reference to a function to be called whenever a leaf node link is clicked. This function should return <code>true</code> or <code>false</code> depending on whether or not the link <code>href</code> should be followed in normal fashion after the function has completed. It should accept a single argument: the event that triggered the link.</p></li>
<li><p><strong>numVisible:</strong> (optional, default: 1) an integer representing the number of visible columns.</p></li>
<li><p><strong>animationSpeed:</strong> (optional, default: 0.25) a number representing the time (in seconds) it takes to complete the scroll animation. If set to 0, animated transitions are turned off and the new menu is moved immediately into place.</p></li>
</ul>

<p>A ColumNav instance exports a single public method: <code>reset()</code> which can be called at any time to revert the component back to its original state.</p>

<h3>CSS</h3>

<p>Two stylesheets are required:</p>

<pre><code>&lt;link href="carousel.css" rel="stylesheet" type="text/css"/&gt;
&lt;link href="columnav.css" rel="stylesheet" type="text/css"/&gt;
</code></pre>

<p>The <code>carousel.css</code> file governs the layout and behavior of the underlying Carousel component, and should not be edited. The <code>columnav.css</code> file can be edited to customize the look and feel of the ColumNav component. Apart from altering fonts, colors, margins, etc., rules can be added to display different icons for each list item type. When the script runs, it introduces three additional CSS class names which you can use to refine the display:</p>

<ul>
<li><p><strong>columnav-has-menu:</strong> designates an item that, when clicked, will produce a sub-menu</p></li>
<li><p><strong>columnav-active:</strong> designates an item that has been clicked</p></li>
<li><p><strong>columnav-error:</strong> designates an error message (occurs when an Ajax request fails)</p></li>
</ul>

<p>In addition to these class names, others can be added to an item by including them in the data source, providing fine-grained CSS control. For example:</p>

<pre><code>&lt;ul&gt;
    &lt;li&gt;&lt;a href="examples/ajax/ncaa/index.xml" class="ncaa" rel="ajax"&gt;NCAA&lt;/a&gt;&lt;li&gt;
&lt;/ul&gt;
</code></pre>

<p>When loaded into the ColumNav, the link above will contain two class names: "ncaa" (propagated from the data source), and "columnav-has-menu" (due to the presence of <code>rel="ajax"</code>). This allows you to display a different icon based on the given class name. For example:</p>

<pre><code>.carousel-component ul.carousel-list li a.ncaa span {
    background-image: url(ncaa-logo.png);
}
</code></pre>

<p>Note the background image belongs to the nested <code>span</code>.</p>

<p>It is important to remember that the data source markup is not copied verbatim into the ColumNav. Instead, it is transformed into a format more suitable for containment within the Carousel component. For instance, when the markup above is translated into the Carousel (e.g. <code>#mycolumnav ul.carousel-list</code>) it looks like this:</p>

<pre><code>&lt;li&gt;
  &lt;div&gt;
    &lt;a href="examples/ajax/ncaa/index.xml" class="ncaa columnav-has-menu"&gt;NCAA&lt;/a&gt;
  &lt;div&gt;
&lt;/li&gt;
</code></pre>

<p>Keep this in mind when styling the ColumNav.</p>

<h2>Tips</h2>

<ul>
<li><p>When the ColumNav has focus, you can use the keyboard to navigate the menus. Hold down the <kbd>CTRL</kbd> key while pressing the arrow keys (the <kbd>CTRL</kbd> key prevents the browser from performing the default action for the arrow keys: scrolling the main browser window).</p></li>
<li><p>When viewing the Ajax examples above or developing your own, be sure to view the pages from a web server instead of locally, or else the connections will fail. Also, be sure that your Ajax responses are sent with the proper mime type: <code>application/xml</code> or <code>application/xhtml+xml</code> for XML data, and <code>application/json</code> for JSON data.</p></li>
<li><p>If having an empty <code>&lt;ul&gt;</code> element in your ColumNav HTML offends your standard-compliant sensibilities, you can insert an empty <code>&lt;li&gt;</code> if you'd like. But make sure you remove it before instantiating the ColumNav, or it might not render properly.</p></li>
<li><p>In Internet Explorer, you might notice the images flickering slightly when you mouse over them. To remedy this, add the following code at the top of your script:</p>

<pre><code>try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}
</code></pre>

<p>See <a href="http://evil.che.lu/2006/9/25/no-more-ie6-background-flicker">http://evil.che.lu/2006/9/25/no-more-ie6-background-flicker</a> for more information.</p></li>
</ul>

<h2>Credits</h2>

<p>My name is <a href="http://stringify.com/">David Lindquist</a>, and I wrote the ColumNav JavaScript, CSS, examples, and this documentation. Many thanks to <a href="http://looksgoodworkswell.com/">Bill Scott</a> for his wonderful Carousel component upon which ColumNav is based, and to the Yahoo UI developers for my favorite JavaScript framework. Special thanks go to <a href="http://markupmonkey.com/">Nate Steiner</a> for suggesting the ColumNav name, and for convincing me to allow for non-Ajax content loading.</p>

<p>Questions? Comments? Send me email at stringify.com, username: david.</p>
<!-- Markdown generated HTML ends here -->
      </div>
    </div>
  </body>
</html>
